package com.jilefojing.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jilefojing.beans.data.enums.ResponseEnum;
import com.jilefojing.beans.enums.ItemTypeEnumForSource;
import com.jilefojing.beans.exception.UserContextException;
import com.jilefojing.beans.pojos.RHotTag;
import com.jilefojing.beans.pojos.Tag;
import com.jilefojing.beans.pojos.base.BasePo;
import com.jilefojing.beans.pojos.enhanced.EnhancedRHotTag;
import com.jilefojing.beans.pojos.enhanced.EnhancedTag;
import com.jilefojing.beans.pojos.enhanced.EnhancedUser;
import com.jilefojing.beans.pojos.enhanced.base.BaseEnhanced;
import com.jilefojing.beans.query.TagQuery;
import com.jilefojing.beans.vo.Order;
import com.jilefojing.beans.vo.Pagination;
import com.jilefojing.context.beans.vo.UserContext;
import com.jilefojing.dao.IRHotTagDao;
import com.jilefojing.dao.IRTagSourceDao;
import com.jilefojing.dao.ITagDao;
import com.jilefojing.service.IRHotTagService;
import com.jilefojing.service.ITagService;
import com.jilefojing.service.IUserService;
import com.jilefojing.service.base.impl.BaseService;
import com.jilefojing.util.Detect;

/**
 * 
 * @author 作者 jgshun
 * @date 创建时间 2016年07月25日 22时00分52秒
 */
@Service
public class TagService extends BaseService<Tag> implements ITagService {
	@Autowired
	private ITagDao tagDao;
	@Autowired
	private IRHotTagService rHotTagService;
	@Autowired
	private IRHotTagDao rHotTagDao;
	@Autowired
	private IRTagSourceDao rTagSourceDao;
	@Autowired
	private IUserService userService;

	@Override
	public EnhancedTag getEnhanced(long id, UserContext userContext) {
		List<EnhancedTag> enhancedTags = this.getEnhanceds(Arrays.asList(new Long[] { id }), userContext);
		if (!Detect.notEmpty(enhancedTags)) {
			return null;
		}
		return enhancedTags.get(0);
	}

	@Override
	public List<EnhancedTag> getEnhanceds(List<Long> ids, UserContext userContext) {
		List<Tag> tags = tagDao.getListByIds(ids);
		if (!Detect.notEmpty(tags)) {
			return null;
		}
		List<EnhancedTag> enhancedTags = this.convent2Enhanceds(tags);
		this.appendEnhancedCommons(enhancedTags, userContext);
		return enhancedTags;
	}

	@Override
	public List<EnhancedTag> appendEnhancedCommons(List<? extends BaseEnhanced> enhancedItems, UserContext userContext) {
		@SuppressWarnings("unchecked")
		List<EnhancedTag> enhancedTags = (List<EnhancedTag>) enhancedItems;
		this.appendEnhancedUser(enhancedTags, userContext);

		return enhancedTags;
	}

	@Override
	public List<EnhancedTag> appendEnhancedUser(List<EnhancedTag> enhancedTags, UserContext userContext) {
		List<Long> userIds = new ArrayList<Long>();
		for (EnhancedTag _EnhancedTag : enhancedTags) {
			if (_EnhancedTag.getEnhancedCreateUser() != null) {
				userIds.add(_EnhancedTag.getEnhancedCreateUser().getId());
			}
		}
		if (!Detect.notEmpty(userIds)) {
			return enhancedTags;
		}

		List<EnhancedUser> enhancedUsers = userService.getEnhancedUsers(userIds);
		if (!Detect.notEmpty(enhancedUsers)) {
			return enhancedTags;
		}
		for (EnhancedTag _EnhancedTag : enhancedTags) {
			if (_EnhancedTag.getEnhancedCreateUser() != null) {
				for (EnhancedUser _EnhancedUser : enhancedUsers) {
					if (_EnhancedTag.getEnhancedCreateUser().getId() == _EnhancedUser.getId()) {
						_EnhancedTag.setEnhancedCreateUser(_EnhancedUser);
						break;
					}
				}
			}
		}
		return enhancedTags;
	}

	@Override
	public List<EnhancedTag> convent2Enhanceds(List<? extends BasePo> pos) {
		@SuppressWarnings("unchecked")
		List<Tag> tags = (List<Tag>) pos;
		List<EnhancedTag> enhancedTags = new ArrayList<EnhancedTag>();
		for (Tag _Tag : tags) {
			enhancedTags.add(new EnhancedTag(_Tag));
		}
		return enhancedTags;
	}

	@Override
	public Pagination<EnhancedTag> getPaginationByItemTypesForHot(List<ItemTypeEnumForSource> itemTypes, Pagination<EnhancedTag> pagination, UserContext userContext) {
		@SuppressWarnings("unchecked")
		Pagination<EnhancedRHotTag> enhancedRHotTagPagination = pagination.copy();
		if (!Detect.notEmpty(pagination.getOrders())) {
			enhancedRHotTagPagination.addOrder(new Order(RHotTag.FIELD_SORT, Order.ORDER_DESC));
		}
		enhancedRHotTagPagination = rHotTagService.getPaginationByItemTypes(itemTypes, enhancedRHotTagPagination, userContext);

		pagination.setCount(enhancedRHotTagPagination.getCount());
		if (!Detect.notEmpty(enhancedRHotTagPagination.getItems())) {
			return pagination;
		}
		rHotTagService.appendEnhancedTag2EnhancedRHotTags(enhancedRHotTagPagination.getItems(), userContext);
		List<EnhancedTag> enhancedTags = new ArrayList<EnhancedTag>();
		for (EnhancedRHotTag _EnhancedRHotTag : enhancedRHotTagPagination.getItems()) {
			enhancedTags.add(_EnhancedRHotTag.getEnhancedTag());
		}
		this.appendCountSourcesByItemTypes(enhancedTags, itemTypes, userContext);
		pagination.setItems(enhancedTags);
		return pagination;
	}

	@Override
	public List<EnhancedTag> appendCountSourcesByItemTypes(List<EnhancedTag> enhancedTags, List<ItemTypeEnumForSource> itemTypes, UserContext userContext) {
		List<Long> tagIds = new ArrayList<Long>();
		for (EnhancedTag _EnhancedTag : enhancedTags) {
			tagIds.add(_EnhancedTag.getId());
		}
		List<Map<String, Object>> counts = rTagSourceDao.countSourcesByItemTypesForTags(tagIds, itemTypes);
		if (Detect.notEmpty(counts)) {
			for (EnhancedTag _EnhancedTag : enhancedTags) {
				for (Map<String, Object> count : counts) {
					if (_EnhancedTag.getId() == Long.valueOf(String.valueOf(count.get("tagId")))) {
						_EnhancedTag.setCountSource(Integer.valueOf(String.valueOf(count.get("count"))));
						break;
					}
				}
			}
		}
		return enhancedTags;
	}

	@Override
	public Pagination<EnhancedTag> getPagination(TagQuery tagQuery, Pagination<EnhancedTag> pagination, UserContext userContext) {
		@SuppressWarnings("unchecked")
		Pagination<Tag> tagPagination = tagDao.getPagination(tagQuery, pagination.copy());
		pagination.setCount(tagPagination.getCount());

		if (!Detect.notEmpty(tagPagination.getItems())) {
			return pagination;
		}
		pagination.setItems(this.convent2Enhanceds(tagPagination.getItems()));
		this.appendEnhancedCommons(pagination.getItems(), userContext);
		return pagination;
	}

	@Override
	public void deleteById(long id, boolean force, UserContext userContext) throws UserContextException {
		this.deleteByIds(Arrays.asList(new Long[] { id }), force, userContext);
	}

	@Override
	public void deleteByIds(List<Long> ids, boolean force, UserContext userContext) throws UserContextException {
		if (force) {
			rTagSourceDao.deleteByTagIds(ids);
			rHotTagDao.deleteByTagIds(ids);
		} else {
			long count = rTagSourceDao.countByTagIds(ids);
			if (count > 0) {
				throw new UserContextException(ResponseEnum.TAG_EXIST_RELATION_SOURCES);
			}
			count = rHotTagDao.countByTagIds(ids);
			if (count > 0) {
				throw new UserContextException(ResponseEnum.TAG_EXIST_RELATION_SOURCES);
			}
		}
		tagDao.deleteByIds(ids, Tag.FIELD_ID, Tag.class);
	}

	@Override
	public Tag add(Tag tag, UserContext userContext) throws UserContextException {
		if (Detect.notEmpty(tag.getName()) && tag.getName().replaceAll(" ", "").length() < 1) {
			throw new UserContextException("[名称不能为空]");
		}
		tag.setId(null);
		tag.setName(tag.getName().replaceAll(" ", ""));
		tag.setCreateTime(new Date());
		tag.setCreateUser(userContext.getUserId());

		List<Tag> tags = tagDao.getListByName(tag.getName());
		if (Detect.notEmpty(tags)) {
			throw new UserContextException("[已存在同名标签]");
		}
		return tagDao.save(tag);
	}

	@Override
	public Tag update(Tag tag, UserContext userContext) throws UserContextException {
		if (Detect.notEmpty(tag.getName()) && tag.getName().replaceAll(" ", "").length() < 1) {
			throw new UserContextException("[名称不能为空]");
		}
		String name = tag.getName().replaceAll(" ", "");

		Tag dbTag = tagDao.getById(tag.getId());
		if (dbTag == null) {
			throw new UserContextException("[标签不存在]");
		}

		List<Tag> tags = tagDao.getListByName(name);
		if (Detect.notEmpty(tags)) {
			if (tags.get(0).getName().equals(name) && tags.get(0).getId() == tag.getId()) {
				return dbTag;
			} else {
				throw new UserContextException("[已存在同名标签]");
			}
		}

		long count = rTagSourceDao.countByTagId(tag.getId());
		if (count > 0) {
			throw new UserContextException(ResponseEnum.TAG_EXIST_RELATION_SOURCES);
		}
		count = rHotTagDao.countByTagId(tag.getId());
		if (count > 0) {
			throw new UserContextException(ResponseEnum.TAG_EXIST_RELATION_SOURCES);
		}

		dbTag.setName(name);

		return tagDao.updateByPrimaryKey(dbTag);

	}
}
